#!/usr/bin/env python3.2
# -*- coding: utf-8 -*-
MAXPAGELENGTH = 5000

import re
from HTMLTags import *
import urllib.parse
translations = Import('../translations.py')
_ = translations.translate
ENCODING = translations.encoding
kt = KT(translate=_, encoding=ENCODING)

wikidoc = Import(THIS.app.wikidoc_module)
wikibase = Import(THIS.app.wikibase_module)
db = wikibase.WikiBase(THIS.app.db_path,THIS.app.db_backend)

"""    
def _log(*args):
    import sys
    for arg in args:
        sys.stderr.write('%s\n' % repr(arg))
"""

def _errormsg(msg):
    title = 'ERROR'
    heading = 'ERROR'
    bodytmpl = 'msg.kt'
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)

def _infomsg(msg):
    title = 'Info'
    heading = ''
    bodytmpl = 'msg.kt'
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)

def index():
    pages = db.pagelist(orderby='lastmodif',limit=5,desc=True)
    pagenames = UL()
    if pages:
        for page in pages:
            wikiname = wikidoc.formatWikiname(page['name'])
            dt = page['lastmodif'].strftime("%Y-%m-%d %H:%M")
            pagenames <= LI(
                A(wikiname, Class="wikiname", href="show/%s" % page['name'], title='Last modified: %s' % dt)
                )
        # Set start character for page lists - first character of first name in list
        startchar = pages[0]['name'][0].upper()
    else:
        pagenames = 'No pages'
        startchar = 'A'
    logout = ''
    if Role()=="admin":
        logout = A(_("Log out"), href="logout") 
    return kt.render('../templates/index.kt', data=locals(),this=THIS)

def show(pageName=None,admin=False,**kw):
    import datetime
    page = db.get(pageName)
    # increment number of visits
    db.put(page, nbvisits=page['nbvisits']+1) 
    b=wikidoc.WikiDoc(pageName, page['content'])
    wikiNames=b.wikiNames
    # insert new pages in the base
    for w_name in wikiNames:
        page = db.get(w_name)
        if not '__id__' in page:
            db.put(page,
                content = 'New page',
                version = 1
            )
    lastmodif = page['lastmodif'].strftime("%d/%m/%y %H:%M")
    html = b.text
    title = '- %s' % wikidoc.formatWikiname(pageName)
    heading = ''
    bodytmpl = 'show.kt'
    return kt.render('../templates/master.kt',data=locals(),page=page,this=THIS,app=THIS.app)

def edit(action="",pageName=None,admin=None,**kw):
    if not wikidoc.isLinkName(pageName):
        msg = TEXT()
        msg <= B(pageName)+_(" is not a valid link name - ")
        msg <=_("Must begin with a Capital and have at least another one inside")
        return _errormsg(msg)
    page = db.get(pageName)
    if '__id__' in page:
        text = page['content']
        admin = page['admin']
    else:
        text = 'New page'
    if admin and not Role()=="admin":
        # Because we are using smart URLs we need to do some 
        # extra work to formulate the origin URL correctly
        script_url = THIS.path_info[:THIS.path_info.find('edit')-1]
        origin = "%s/edit/%s?admin=on" % (script_url, pageName)
        Login(role='admin',origin=origin)
    adminchecked = 'CHECKED' if admin else ''
    title = '- %s %s' % (_('editing'), wikidoc.formatWikiname(pageName))
    heading = '%s %s' % (_('Editing page'), pageName)
    jstmpl = 'editjs.kt'
    bodytmpl = 'edit.kt'
    return kt('../templates/master.kt', data=locals(),this=THIS,app=THIS.app)
    
def save(pageName='', newText='', admin=0):
    import datetime
    if len(newText)>MAXPAGELENGTH:
        msg = TEXT('Length of text %s exceeds maximum page length %s' \
            % (len(newText),MAXPAGELENGTH))
        return _errormsg(msg)
    if admin and not Role()=="admin":
        msg = 'You must be logged in as admin to set this page to admin status.<br>\n'
        if Role():
            msg += 'Your role is: %s.' % Role()
        else:
            msg += 'You are not currently logged in.'
        return _errormsg(msg)
    page = db.get(pageName)
    db.put(page, 
        content = newText.rstrip(),
        admin = admin,
        version = page['version'] + 1,
        lastmodif = datetime.datetime.now()  
        )
    raise HTTP_REDIRECTION("show/%s" % pageName)

def _replace(matchObj):
    return "<b>"+matchObj.string[matchObj.start():matchObj.end()]+"</b>"

def search(words,caseSensitive=False,fullWord=False):
    # search engine
    import posixpath
    words2 = "(%s)" %words
    if fullWord:
        words2=r"\W"+words2+r"\W"
    sentence="[\n\r.?!].*"+words2+".*[\n\r.?!]"
    #sentence=words
    if caseSensitive:
        sentencePattern=re.compile(sentence, re.UNICODE)
        wordPattern=re.compile(words2, re.UNICODE)
    else:
        sentencePattern=re.compile(sentence,re.IGNORECASE|re.UNICODE)
        wordPattern=re.compile(words2,re.IGNORECASE|re.UNICODE)        
    occ=0           # number of occurences
    result = TEXT()     # formatted results
    # gets all pages in base
    for page in db.iter_pages():
        content = '\n'+page['content']+'\n'
        name = page['name']
        wikiname = wikidoc.formatWikiname(name)
        try:
            content = str(content, 'utf-8')
        except TypeError:
            pass
        # content="\n"+wikiname+"\n"+content+"\n"
        flag=0  # true if at least one match
        deb=0
        while 1:
            searchObj=sentencePattern.search(content,deb)
            if searchObj is None:
                if flag:
                    result <= found
                break
            else:
                if not flag:
                    # name = page['name']
                    # wikiname = wikidoc.formatWikiname(name)
                    result <= A(wikiname, Class="wikiname", href="show/%s" %name) + BR()
                    found = BLOCKQUOTE()
                    flag=1
                sentence=content[searchObj.start():searchObj.end()]
                sentence=sentence.lstrip()
                # eliminates leading char "!"
                sentence=sentence[re.search("[^!]",sentence).start():]
                sentence=wordPattern.sub(_replace,sentence)
                found <= TEXT(sentence)+BR()
                deb=searchObj.end()-len(words)+1
                occ+=1
                flag=1
    msg = ""
    if not occ:
        msg = "%s not found" %words
    title = ' - search results'
    heading = 'Searching for [%s]' %words
    bodytmpl = 'search.kt'
    firstchar = words[0].upper()
    caseSensitiveChecked = 'CHECKED' if caseSensitive else ''
    fullWordChecked = 'CHECKED' if fullWord else ''
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)


def pagesbytitle(char='A'):
    import cgi
    char = char.upper()
    result = TEXT()
    index = dict([(c, False) for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"])
    pagesExist = False
    for page in db.iter_pages():
        firstchar = page['name'][0].upper()
        index[firstchar] = True
        if firstchar == char:
            pagesExist = True
            name = page['name']
            wikiname = wikidoc.formatWikiname(name)
            result <= A(wikiname, Class="wikiname", href="show/%s" % name) + BR()
            # Get first paragraph
            content = page['content'].strip()
            lines = content.split('\n', 3)[:3]
            result <= BLOCKQUOTE(Sum([TEXT(cgi.escape(l)) + BR() for l in lines]))
        elif firstchar > char:
            break
    index = list(index.items())
    index.sort()
    indexhtml = TEXT()
    for c, flag in index:
        if c == char:
            indexhtml <= FONT(c + ' ', size='+1')
        elif flag:
            indexhtml <= A(c, href="pagesbytitle?char=%s" % c) + TEXT(' ')
        else:
            indexhtml <= TEXT(c + ' ')
    if not pagesExist:
        result = 'No page titles beginning with "%s"' % char
    title = _('Pages By Title')
    heading = _('Pages By Title')
    bodytmpl = 'pagelist.kt'
    altpagelist = A(_('Pages By Keyword'), href='pagesbykeyword?char=%s' % char)
    try:
        content = str(result)
    except UnicodeEncodeError:
        content = '%s' % result
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)

def pagesbykeyword(char='A'):
    import cgi
    char = char.upper()
    index = dict([(c, False) for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"])
    keywords = {}
    pagesExist = False
    for page in db.iter_pages():
        name = page['name']
        wikiwords = wikidoc.getWikiwords(name)
        for word in wikiwords:
            firstchar = word[0].upper()
            index[firstchar] = True
            if firstchar == char:
                pagesExist = True
                if word not in keywords:
                    keywords[word] = [name]
                else:
                    keywords[word].append(name)
    keys = list(keywords.keys())
    keys.sort()
    result = TEXT()
    for key in keys:
        result <= H3(key)
        keyresult = BLOCKQUOTE()
        names = keywords[key]
        names.sort()
        for name in names:
            page = db.get(name)
            wikiname = wikidoc.formatWikiname(name)
            keyresult <= A(wikiname, Class="wikiname", href="show/%s" %name) + BR()
            # Get first paragraph
            content = page['content'].strip()
            lines = content.split('\n', 3)[:3]
            keyresult <= BLOCKQUOTE(Sum([TEXT(cgi.escape(l)) + BR() for l in lines]))
        result <= keyresult
    index = list(index.items())
    index.sort()
    indexhtml = TEXT()
    for c, flag in index:
        if c == char:
            indexhtml <= FONT(c + ' ', size='+1')
        elif flag:
            indexhtml <= A(c, href="pagesbykeyword?char=%s" % c) + TEXT(' ')
        else:
            indexhtml <= TEXT(c + ' ')
    if not pagesExist:
        result = 'No title keywords beginning with "%s"' % char
    title = _('Pages By Keyword')
    heading = _('Pages By Keyword')
    altpagelist = A(_('Pages By Title'), href='pagesbytitle?char=%s' % char)
    bodytmpl = 'pagelist.kt'
    try:
        content = str(result)
    except UnicodeEncodeError:
        content = '%s' % result
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)

    
def remove(subm=None,remove=[]):
    """ Removes the pages whose names are the keys of QUERY """
    # check authentication
    Login(role="admin")
    if subm == _("Cancel") or not remove:
        raise HTTP_REDIRECTION("index")
    # get records to remove using their recno
    pagelist = ''
    for r in remove:
        pagelist += '<li>%(name)s</li>' % db.get(r)
    if len(remove) == 1:
        msg = "1 page deleted<p>\n"
    else:
        msg = "%s pages deleted<p>\n" %len(remove) 
    # Remove the records from the database
    for r in remove:
        db.delete(r)
    title = ' - removing pages'
    heading = _('Removing pages')
    bodytmpl = 'remove.kt'
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)

def admin():
    if not Role() == "admin":
        Login(role="admin") # ,origin=THIS.path)
    pages = db.pagelist()
    if not pages:
        return('No page to remove<p><a href="index">Back</a>')
    pagelist = TEXT()
    for page in pages:
        row = TR()
        row <= TD(INPUT(type="checkbox",name="remove[]",value=page['name']))
        row <= TD('&nbsp;%s' % page['name'])
        pagelist <= row
    title = '- admin'
    heading = _('Administration')
    bodytmpl = 'admin.kt'
    return kt('../templates/master.kt',data=locals(),this=THIS,app=THIS.app)
    
def logout():
    Logout(redir_to=THIS.root_url)
            